﻿using System;
using System.Windows.Forms;
using AiFrame.InterfaceLib.MVP;

namespace AiFrame.InterfaceLib.Data.Patterns
{
    /// <summary>
    /// Dient als Managing Object, um das Anzeigen mehrerer Fenster
    /// in einem Parent-Control über eine einheitliche Schnittstelle
    /// zu steuern.
    /// </summary>
    public class WindowManager : IWindowManager<IAbstractWindow>
    {
        private ObservableCollection<IAbstractWindow> _windowCollec;
        private static WindowManager pInstance;
        private Control _parentControl;
        private IAbstractWindow _activeWindow;

        public static WindowManager Instance()
        {
            /* Überprüfen, ob es schon eine Instanz gibt.
             * Wenn nicht, soll eine erzeugt werden. */
            if (pInstance == null)
            {
                pInstance = new WindowManager();
            }
            return pInstance;
        }

        protected WindowManager()
        {
            _windowCollec = new ObservableCollection<IAbstractWindow>();
        }

        /// <summary>
        /// Initialisiert den TabSetManager.
        /// Muss aufgerufen werden, bevor Fenster angezeigt werden können.
        /// </summary>
        public void Initialize(Control parentControl)
        {
            _parentControl = parentControl;
        }

        #region Implementation of IWindowManager

        public virtual void RegisterWindow(IAbstractWindow window)
        {
            if (_parentControl == null)
                throw new MissingInitialisationException("Der WindowManager muss zuerst initialisiert werden.");

            window.SetParentWindow(_parentControl);
            OnActiveWindowChanged(window);
        }

        public void CloseWindow(IAbstractWindow window)
        {
            _windowCollec.Remove(window);
            OnActiveWindowChanged(window);
        }

        public bool ExistsWindow<W>()
        {
            if (GetWindowTypeIndex<W>() == -1)
                return false;

            return true;
        }

        /// <summary>
        /// Gibt den Index eines Fensters, welches von einem bestimmten Typ ist,
        /// zurück.
        /// </summary>
        /// <typeparam name="W"></typeparam>
        /// <returns></returns>
        private int GetWindowTypeIndex<W>()
        {
            for (int i = 0; i < _windowCollec.Count; i++)
            {
                /* Falls der Typ existiert, true zurückgeben! */
                if (_windowCollec[i] is W)
                {
                    return i;
                }
            }
            return -1;
        }

        public void BringWindowToFront<W>()
        {
            int index = GetWindowTypeIndex<W>();

            /* Falls das Fenster nicht in der Liste existiert, nichts tun.
             * Der Entwickler ist selbst dafür verantwortlich, vorher nachzuschauen,
             * ob es dieses Fenster auch gibt. */
            if (index != -1)
            {
                _windowCollec[index].BringWindowToFront();
                OnActiveWindowChanged(_windowCollec[index]);
            }
        }

        public IAbstractWindow ActiveWindow
        {
            get { return _activeWindow; }
        }

        public event EventHandler<ActiveWindowChangedParams<IAbstractWindow>> ActiveWindowChanged;
        public event EventHandler<ActiveWindowChangedParams<IAbstractWindow>> ActiveWindowChanges;

        protected void OnActiveWindowChanged(IAbstractWindow window)
        {
            if (ActiveWindowChanged != null)
                ActiveWindowChanged(this, new ActiveWindowChangedParams<IAbstractWindow>(window));

            _activeWindow = window;
        }

        #endregion

        #region Implementation of IShortCuts

        public void RefreshView()
        {
            throw new System.NotImplementedException();
        }

        #endregion
    }
}
